home *** CD-ROM | disk | FTP | other *** search
/ Delphi 5 for Professionals / DELPHI5.iso / AddOns / Components / TEECHART / Src Code / TEESCROB.PAS < prev    next >
Encoding:
Pascal/Delphi Source File  |  1998-10-24  |  9.1 KB  |  313 lines

  1. {******************************************}
  2. {    TeeChart Pro ScrollBar component      }
  3. { Copyright (c) 1997-1998 by David Berneda }
  4. {         All Rights Reserved              }
  5. {******************************************}
  6. {$I teedefs.inc}
  7. unit TeeScroB;
  8.  
  9. interface
  10.  
  11. { This unit implements the TChartScrollBar component.
  12.   This is a specialized TScrollBar component to scroll Series points.
  13.  
  14.   Note: Do not modify the "Min" and "Max" properties of the ScrollBar,
  15.         because they are overriden and calculated internally.
  16.  
  17.         Use the Axis Minimum and Maximum properties to change the ScrollBar
  18.         position.
  19. }
  20.  
  21. uses
  22.   Wintypes, WinProcs, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  23.   StdCtrls, Teengine, Chart;
  24.  
  25. Const TeeMaxScrollPos=30000;
  26.  
  27. type
  28.   { Depending if the ScrollBar is Horizontal or Vertical:
  29.  
  30.     sbDefault: means Left or Bottom axis
  31.     sbOther  : means Right or Top axis
  32.     sbBoth   : (default) means Left and Bottom , or Right and Top axis
  33.  
  34.   }
  35.   TScrollBarAxis=(sbDefault,sbOther,sbBoth);
  36.  
  37.  
  38.   TChartScrollBar = class(TScrollBar)
  39.   private
  40.     { Private declarations }
  41.     FAxis          : TScrollBarAxis;
  42.     FChart         : TCustomChart;
  43.     FInverted      : Boolean;
  44.     FOldOnScroll   : TNotifyEvent;
  45.     FOldOnZoom     : TNotifyEvent;
  46.     FOldOnUndoZoom : TNotifyEvent;
  47.     {$IFNDEF D1}
  48.     FPageSize      : Integer;
  49.     procedure SetPageSize(Value:Integer);
  50.     {$ENDIF}
  51.     Procedure SetChart(Value:TCustomChart);
  52.     Procedure SetInverted(Value:Boolean);
  53.     Procedure ChartOnScroll(Sender:TObject);
  54.     Procedure ChartOnZoom(Sender:TObject);
  55.     Procedure ChartOnUndoZoom(Sender:TObject);
  56.     Procedure CalcTotals(Axis:TChartAxis; Var AMin,AMax:Double);
  57.   protected
  58.     { Protected declarations }
  59.     procedure Scroll(ScrollCode: TScrollCode; var ScrollPos: Integer); override;
  60.     Function AssociatedSeries(Axis:TChartAxis):Integer;
  61.   public
  62.     { Public declarations }
  63.     constructor Create(AOwner : TComponent); override;
  64.     procedure Notification( AComponent: TComponent;
  65.                             Operation: TOperation); override;
  66.     Procedure RecalcPosition;
  67.   published
  68.     { Published declarations }
  69.     property Align;
  70.     property Axis:TScrollBarAxis read FAxis write FAxis default sbBoth;
  71.     property Chart:TCustomChart read FChart write SetChart;
  72.     property Enabled default False;
  73.     property Inverted:Boolean read FInverted write SetInverted default False;
  74.     property LargeChange default 500;
  75.     property Max default TeeMaxScrollPos;
  76.     property SmallChange default 50;
  77.     {$IFNDEF D1}
  78.     property PageSize:integer read FPageSize write SetPageSize;
  79.     {$ENDIF}
  80.   end;
  81.  
  82. implementation
  83.  
  84. { TChartScrollBar }
  85. Constructor TChartScrollBar.Create(AOwner : TComponent);
  86. begin
  87.   inherited Create(AOwner);
  88.   FAxis:=sbBoth;
  89.   SetParams(0,0,TeeMaxScrollPos);
  90.   LargeChange:=TeeMaxScrollPos div 10;
  91.   SmallChange:=TeeMaxScrollPos div 100;
  92.   Enabled:=False;
  93.   FInverted:=False;
  94. end;
  95.  
  96. { How many Series are associated to this Axis? }
  97. Function TChartScrollBar.AssociatedSeries(Axis:TChartAxis):Integer;
  98. var t:Integer;
  99. begin
  100.   result:=0;
  101.   With Axis.ParentChart do
  102.   for t:=0 to SeriesCount-1 do
  103.       if Series[t].AssociatedToAxis(Axis) then Inc(result);
  104. end;
  105.  
  106. { When the user clicks on the scroll bar, change the Chart Axis min and max }
  107. procedure TChartScrollBar.Scroll(ScrollCode: TScrollCode; var ScrollPos: Integer);
  108. var tmpPos : Integer;
  109.  
  110.   Procedure ScrollAxis(Axis:TChartAxis);
  111.   var MidRange : Double;
  112.       Middle   : Double;
  113.       TotalMin : Double;
  114.       TotalMax : Double;
  115.   begin
  116.     if AssociatedSeries(Axis)>0 then
  117.     begin
  118.       {$IFNDEF D1}
  119.       tmpPos:=tmpPos+(FPageSize div 2);
  120.       {$ENDIF}
  121.       CalcTotals(Axis,TotalMin,TotalMax);
  122.       Middle:=(TotalMax-TotalMin)*tmpPos/(Max-Min);
  123.       MidRange:=(Axis.Maximum-Axis.Minimum)/2.0;
  124.       Axis.SetMinMax(Middle-MidRange,Middle+MidRange);
  125.     end;
  126.   end;
  127.  
  128. begin
  129.   inherited Scroll(ScrollCode,ScrollPos);
  130.   if Assigned(FChart) then
  131.     if ScrollPos<>Position then
  132.     begin
  133.       if Kind=sbHorizontal then
  134.       begin
  135.         if Inverted then tmpPos:=Max-Position else tmpPos:=Position;
  136.         if (FAxis=sbBoth) or (FAxis=sbDefault) then ScrollAxis(FChart.BottomAxis);
  137.         if (FAxis=sbBoth) or (FAxis=sbOther) then ScrollAxis(FChart.TopAxis);
  138.       end
  139.       else
  140.       begin
  141.         if Inverted then tmpPos:=Position else tmpPos:=Max-Position;
  142.         if (FAxis=sbBoth) or (FAxis=sbDefault) then ScrollAxis(FChart.LeftAxis);
  143.         if (FAxis=sbBoth) or (FAxis=sbOther) then ScrollAxis(FChart.RightAxis);
  144.       end;
  145.     end;
  146. end;
  147.  
  148. { When the Chart is removed at design-time or run-time }
  149. procedure TChartScrollBar.Notification( AComponent: TComponent;
  150.                                         Operation: TOperation);
  151. begin
  152.   inherited Notification(AComponent, Operation);
  153.   if Operation=opRemove then
  154.      if Assigned(FChart) and (AComponent=FChart) then Chart:=nil;
  155. end;
  156.  
  157. { When the user scrolls the chart using the right mouse button }
  158. Procedure TChartScrollBar.ChartOnScroll(Sender:TObject);
  159. begin
  160.   RecalcPosition;
  161.   if Assigned(FOldOnScroll) then FOldOnScroll(FChart);
  162. end;
  163.  
  164. { When the user zooms the chart using the left mouse button }
  165. Procedure TChartScrollBar.ChartOnZoom(Sender:TObject);
  166. begin
  167.   RecalcPosition;
  168.   if Assigned(FOldOnZoom) then FOldOnZoom(FChart);
  169. end;
  170.  
  171. { When the user undoes any previous zoom using the left mouse button }
  172. Procedure TChartScrollBar.ChartOnUndoZoom(Sender:TObject);
  173. begin
  174.   RecalcPosition;
  175.   if Assigned(FOldOnUndoZoom) then FOldOnUndoZoom(FChart);
  176. end;
  177.  
  178. { Calculate the lowest and highest possible values for the Axis }
  179. Procedure TChartScrollBar.CalcTotals(Axis:TChartAxis; Var AMin,AMax:Double);
  180. Var OldAuto : Boolean;
  181.     OldMin  : Double;
  182.     OldMax  : Double;
  183. begin
  184.   OldAuto:=Axis.Automatic;
  185.   OldMin:=Axis.Minimum;
  186.   OldMax:=Axis.Maximum;
  187.   Axis.Automatic:=True;
  188.   try
  189.     Axis.CalcMinMax(AMin,AMax);
  190.   finally
  191.     Axis.Automatic:=OldAuto;
  192.     if not Axis.Automatic then Axis.SetMinMax(OldMin,OldMax);
  193.   end;
  194. end;
  195.  
  196. { Change the scroll bar position and thumb size }
  197. Procedure TChartScrollBar.RecalcPosition;
  198.  
  199.   Procedure RecalcAxis(Axis:TChartAxis);
  200.   var Range       : Double;
  201.       TotalMax    : Double;
  202.       TotalMin    : Double;
  203.       Middle      : Double;
  204.       tmpPosition : LongInt;
  205.   begin
  206.     if AssociatedSeries(Axis)>0 then
  207.     begin
  208.       if Axis.Automatic then
  209.       begin
  210.         Position:=(Min+Max) div 2; { center scroll }
  211.         {$IFNDEF D1}
  212.         PageSize:=Max-Min;
  213.         {$ENDIF}
  214.       end
  215.       else
  216.       begin
  217.         CalcTotals(Axis,TotalMin,TotalMax);
  218.         Range:=TotalMax-TotalMin;
  219.         if Range<>0 then
  220.         begin
  221.           Middle:=(Axis.Minimum+Axis.Maximum)/2.0;
  222.           tmpPosition:=Round(Max*(Middle-TotalMin)/Range);
  223.           if tmpPosition>Max then tmpPosition:=Max;
  224.           if tmpPosition<Min then tmpPosition:=Min;
  225.           if ((Kind=sbVertical) and (not FInverted)) or
  226.              ((Kind=sbHorizontal) and (FInverted)) then tmpPosition:=Max-tmpPosition;
  227.           {$IFNDEF D1}
  228.           PageSize:=Round((Axis.Maximum-Axis.Minimum)*(Max-Min)/Range);
  229.           tmpPosition:=tmpPosition-(PageSize div 2);
  230.           {$ENDIF}
  231.           Position:=tmpPosition;
  232.         end;
  233.       end;
  234.     end;
  235.   end;
  236.  
  237. begin
  238.   if Assigned(FChart) then
  239.     if Kind=sbHorizontal then
  240.     begin
  241.       if (FAxis=sbBoth) or (FAxis=sbDefault) then RecalcAxis(FChart.BottomAxis);
  242.       if (FAxis=sbBoth) or (FAxis=sbOther) then RecalcAxis(FChart.TopAxis);
  243.     end
  244.     else
  245.     begin
  246.       if (FAxis=sbBoth) or (FAxis=sbDefault) then RecalcAxis(FChart.LeftAxis);
  247.       if (FAxis=sbBoth) or (FAxis=sbOther) then RecalcAxis(FChart.RightAxis);
  248.     end;
  249. end;
  250.  
  251. Procedure TChartScrollBar.SetChart(Value:TCustomChart);
  252. begin
  253.   if FChart<>Value then
  254.   begin
  255.     FChart:=Value;
  256.     if Assigned(FChart) then
  257.     begin
  258.       FOldOnScroll:=FChart.OnScroll;
  259.       FChart.OnScroll:=ChartOnScroll;
  260.  
  261.       FOldOnZoom:=FChart.OnZoom;
  262.       FChart.OnZoom:=ChartOnZoom;
  263.  
  264.       FOldOnUndoZoom:=FChart.OnUndoZoom;
  265.       FChart.OnUndoZoom:=ChartOnUndoZoom;
  266.  
  267.       {$IFNDEF D1}
  268.       FChart.FreeNotification(Self);
  269.       {$ENDIF}
  270.       Enabled:=FChart.SeriesCount>0;
  271.       RecalcPosition;
  272.     end
  273.     else
  274.     begin
  275.       Enabled:=False;
  276.       FOldOnScroll:=nil;
  277.       FOldOnZoom:=nil;
  278.       FOldOnUndoZoom:=nil;
  279.     end;
  280.   end;
  281. end;
  282.  
  283. Procedure TChartScrollBar.SetInverted(Value:Boolean);
  284. begin
  285.   if FInverted<>Value then
  286.   begin
  287.     FInverted:=Value;
  288.     RecalcPosition;
  289.   end;
  290. end;
  291.  
  292. {$IFNDEF D1}
  293. { Change the scroll bar thumb size }
  294. procedure TChartScrollbar.SetPageSize(Value:Integer);
  295. var tmp:TScrollInfo;
  296. begin
  297.   if FPageSize<>Value then
  298.   begin
  299.     FPageSize:=Value;
  300. {    tmp.cbSize:=SizeOf(tmp);
  301.     tmp.fMask:=SIF_RANGE+SIF_POS;
  302.     GetScrollInfo(Handle,SB_CTL,tmp);
  303.     tmp.nPos:=Position;}
  304.     tmp.nPage:=FPageSize;
  305. {    tmp.cbSize:=SizeOf(tmp);}
  306.     tmp.fMask:={SIF_RANGE+SIF_POS+}SIF_PAGE;
  307.     SetScrollInfo(Handle,SB_CTL,tmp,True);
  308.   end;
  309. end;
  310. {$ENDIF}
  311.  
  312. end.
  313.